package com.wudizaba.nb;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * io流
 *
 */
@SpringBootTest
@Slf4j
class JavaSeTestIOStream {

    /**
     * 字节输入流读取文件大法
     */
    @Test
    void FileInputStream() {
        log.info("字节输入流读取文件大法开始运行.......");
        File file = new File("D:\\devwork\\ideawork\\JAVA_SE_TEST\\src\\main\\resources\\static\\File\\FileInputStream.txt");
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            //准备一个字节数组，一次可读取多少字节
            byte[] bytes = new byte[1024];
            // 这个方法的返回值是：读取到的字节数量。（不是字节本身）;1个字节都没有读取到返回-1(文件读到末尾)
            int record = 0;
            while ((record = fileInputStream.read(bytes)) != -1) {
                log.info("读取的数据：{}", new String(bytes, 0, record));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 在finally语句块当中确保流一定关闭。
            if (fileInputStream != null) {
                // 关闭流的前提是：流不是空。流是null的时候没必要关闭。
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        log.info("字节输入流读取文件大法运行结束.......");
    }


    /**
     * 字节输出流写入文件大法
     */
    @Test
    void FileOutputStream() {
        log.info("字节输出流写入文件大法开始运行.......");
        File file = new File("D:\\devwork\\ideawork\\JAVA_SE_TEST\\src\\main\\resources\\static\\File\\" + "FileOutputStream" + System.currentTimeMillis() + ".txt");
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            String data = "六、java.io.FileOutputStream\n" +
                    "构造方法\n" +
                    "构造方法名\t备注\n" +
                    "FileOutputStream(String name)\tname为文件路径\n" +
                    "FileOutputStream(String name, boolean append)\tname为文件路径，append为true表示在文件末尾追加；为false表示清空文件内容，重新写入\n" +
                    "FileOutputStream(File file)\t\n" +
                    "FileOutputStream(File file, boolean append)\tappend为true表示在文件末尾追加；为false表示清空文件内容，重新写入\n" +
                    "方法\n" +
                    "方法名\t作用\n" +
                    "void write(int b)\t将指定字节写入文件中\n" +
                    "void write(byte[] b)\t将b.length个字节写入文件中\n" +
                    "void write(byte[] b, int off, int len)\t将b素组off位置开始，len长度的字节写入文件中\n" +
                    "void flush()\t刷新此输出流并强制写出所有缓冲的输出字节\n" +
                    "void close()\t关闭文件输出流\n";
            // file文件不存在的时候会自动新建！
            // 这种方式谨慎使用，这种方式会先将原文件清空，然后重新写入。
            fileOutputStream.write(data.getBytes(StandardCharsets.UTF_8));

            // 这种方式不会清空文件内容，直接追加在末尾
//            fileOutputStream.write("我是文件末尾".getBytes(StandardCharsets.UTF_8),true);
            // 写完之后，最后一定要刷新
            fileOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        log.info("字节输出流写入文件大法运行结束.......");
    }

    /**
     * 缓冲字节输入流读取文件大法
     */
    @Test
    void BufferedReader() {
        log.info("缓冲输入流读取文件大法开始运行........");
//        // 字节流
//        FileInputStream in = new FileInputStream("Copy02.java");
//
//        // 通过转换流转换（InputStreamReader将字节流转换成字符流。）
//        // in是节点流。reader是包装流。
//        InputStreamReader reader = new InputStreamReader(in);
//
//        // 这个构造方法只能传一个字符流。不能传字节流。
//        // reader是节点流。br是包装流。
//        BufferedReader br = new BufferedReader(reader);
        FileInputStream fileInputStream = null;
        BufferedReader bufferedReader = null;
        try {
            fileInputStream = new FileInputStream("D:\\devwork\\ideawork\\JAVA_SE_TEST\\src\\main\\resources\\static\\File\\InputStreamReader.txt");
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            bufferedReader = new BufferedReader(inputStreamReader);

            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println("读取的数据：");
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        log.info("缓冲字节输入流读取文件大法运行结束........");
    }

    /**
     * 缓冲输出流写入文件大法
     */
    @Test
    void BufferedWriter() {
        log.info("缓冲输出流写入文件大法开始运行......");
        String data = "十、java.io.BufferedWriter、 java.io.OutputStreamWriter\n" +
                "BufferedWriter：带有缓冲的字符输出流。\n" +
                "OutputStreamWriter：字节输出流转字符输出流\n" +
                "\n" +
                "构造方法\n" +
                "构造方法名\t备注\n" +
                "BufferedWriter(Writer out)\tout为Writer对象（可以是reader的实现类）\n" +
                "方法\n" +
                "方法名\t作用\n" +
                "void write(int c)\t将指定字符写入文件中\n" +
                "void write(char[] c, int off, int len)\t将c素组off位置开始，len长度的字符写入文件中\n" +
                "void write(String str, int off, int len)\t从字符串off位置开始截取len长度的字符串写入文件\n" +
                "void flush()\t刷新此输出流并强制写出所有缓冲的输出字符\n" +
                "void close()\t关闭文件输出流\n";
        File file = new File("D:\\devwork\\ideawork\\JAVA_SE_TEST\\src\\main\\resources\\static\\File\\" + "BufferedWriter" + System.currentTimeMillis() + ".txt");
        OutputStream outputStream = null;
        BufferedWriter bufferedWriter = null;
        try {
            outputStream = new FileOutputStream(file);
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            bufferedWriter.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        log.info("缓冲输出流写入文件大法运行结束......");
    }
}
